package com.example.demo.exception;

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

/**
 * 自定义业务码枚举（基于HTTP状态码扩展）
 *
 * <p>设计规则：
 * 1. 业务码格式：{HTTP状态码大类}000+{细分编号}（如2xx对应20000+）
 * 2. 区间划分与HTTP状态码语义保持一致，便于前后端理解
 *
 * @author 开发者名称
 * @date 2025-07-15
 */
@Getter
@AllArgsConstructor
public enum ErrorConstants {

    /* -------------------------- 1xx 信息性状态码（100~199） -------------------------- */
    /** HTTP 100：客户端可继续发送请求体 */
    INFO_CONTINUE("请继续发送请求体", 10001, HttpStatus.CONTINUE),

    /** HTTP 101：服务器将切换协议（如升级到WebSocket） */
    INFO_SWITCH_PROTOCOL("服务器将切换至%s协议", 10101, HttpStatus.SWITCHING_PROTOCOLS),

    /* -------------------------- 2xx 成功状态码（200~299） -------------------------- */
    /** HTTP 200：请求成功（通用） */
    SUCCESS_OK("操作成功", 20001, HttpStatus.OK),

    /** HTTP 201：资源创建成功 */
    SUCCESS_CREATED("%s创建成功", 20101, HttpStatus.CREATED),

    /** HTTP 202：请求已接收，正在处理（异步） */
    SUCCESS_ACCEPTED("请求已接收，正在处理", 20201, HttpStatus.ACCEPTED),

    /** HTTP 203：非权威信息（数据来自缓存或代理） */
    SUCCESS_NON_AUTHORITATIVE("数据来自缓存，非原始服务器", 20301, HttpStatus.NON_AUTHORITATIVE_INFORMATION),

    /** HTTP 204：操作成功，无数据返回 */
    SUCCESS_NO_CONTENT("操作成功，无数据返回", 20401, HttpStatus.NO_CONTENT),

    /** HTTP 205：重置内容（需客户端重置视图） */
    SUCCESS_RESET_CONTENT("请重置视图（如清空表单）", 20501, HttpStatus.RESET_CONTENT),

    /** HTTP 206：部分内容返回成功（范围请求） */
    SUCCESS_PARTIAL_CONTENT("已返回部分内容（范围：%s-%s）", 20601, HttpStatus.PARTIAL_CONTENT),

    /* -------------------------- 3xx 重定向状态码（300~399） -------------------------- */
    /** HTTP 300：资源存在多个版本，需客户端选择 */
    REDIRECT_MULTIPLE_CHOICES("资源存在多个版本，请选择", 30001, HttpStatus.MULTIPLE_CHOICES),

    /** HTTP 301：资源永久迁移至新URL */
    REDIRECT_PERMANENT("资源已永久迁移至：%s", 30101, HttpStatus.MOVED_PERMANENTLY),

    /** HTTP 302：资源临时迁移至新URL */
    REDIRECT_TEMPORARY("资源临时迁移至：%s", 30201, HttpStatus.FOUND),

    /** HTTP 303：使用GET方法访问新URL */
    REDIRECT_SEE_OTHER("请使用GET访问：%s", 30301, HttpStatus.SEE_OTHER),

    /** HTTP 304：资源未修改，使用缓存 */
    REDIRECT_NOT_MODIFIED("资源未修改，使用缓存", 30401, HttpStatus.NOT_MODIFIED),

    /** HTTP 307：临时重定向（保持原请求方法） */
    REDIRECT_TEMPORARY_SAME_METHOD("临时重定向至：%s（保持原请求方法）", 30701, HttpStatus.TEMPORARY_REDIRECT),

    /* -------------------------- 4xx 客户端错误状态码（400~499） -------------------------- */

    /** HTTP 400：操作失败（通用） */
    OPERATION_FAIL("操作失败", 40000, HttpStatus.BAD_REQUEST),

    /** HTTP 400：默认参数错误 */
    CLIENT_DEFAULT_PARAM_ERROR("参数校验失败", 40001, HttpStatus.BAD_REQUEST),

    /** HTTP 400：sign 参数错误 */
    CLIENT_SING_PARAM_ERROR("参数校验失败", 40002, HttpStatus.BAD_REQUEST),

    /** HTTP 400：缺少参数 */
    CLIENT_LESS_PARAM_ERROR("%s参数不能为空", 40003, HttpStatus.BAD_REQUEST),

    /** HTTP 400：参数格式错误 */
    CLIENT_PARAM_FORMAT_ERROR("%s参数格式错误,期望：%s", 40004, HttpStatus.BAD_REQUEST),

    /** HTTP 400：请求体格式错误（如JSON解析失败） */
    CLIENT_BODY_FORMAT_ERROR("请求体格式错误", 40005, HttpStatus.BAD_REQUEST),

    /** HTTP 401：无效的认证凭证（Token无效） */
    CLIENT_TOKEN_INVALID("无效的登录凭证", 40101, HttpStatus.UNAUTHORIZED),

    /** HTTP 401：过期的认证凭证 */
    CLIENT_TOKEN_EXPIRED("过期的认证凭证", 40102, HttpStatus.UNAUTHORIZED),

    /** HTTP 403：权限不足（无操作权限） */
    CLIENT_PERMISSION_DENIED("权限不足：%s", 40301, HttpStatus.FORBIDDEN),

    /** HTTP 403：角色不符（无操作权限） */
    CLIENT_ROLE_MISMATCH("角色不符：%s", 40302, HttpStatus.FORBIDDEN),

    /** HTTP 403：账号被封禁 */
    CLIENT_ACCOUNT_BANNED("账号已被封禁：%s", 40303, HttpStatus.FORBIDDEN),

    /** HTTP 404：资源不存在 */
    CLIENT_RESOURCE_NOT_FOUND("%s不存在（ID：%s）", 40401, HttpStatus.NOT_FOUND),

    /** HTTP 404：接口不存在 */
    CLIENT_API_NOT_FOUND("接口不存在：%s", 40402, HttpStatus.NOT_FOUND),

    /** HTTP 405：不支持的请求方法 */
    CLIENT_METHOD_NOT_ALLOWED("接口不支持%s方法（支持：%s）", 40501, HttpStatus.METHOD_NOT_ALLOWED),

    /** HTTP 406：不支持的响应格式 */
    CLIENT_ACCEPT_NOT_SUPPORTED("不支持的响应格式：%s", 40601, HttpStatus.NOT_ACCEPTABLE),

    /** HTTP 402：需要付费访问 (保留状态码) */
    CLIENT_PAYMENT_REQUIRED("此资源需要付费：%s", 40201, HttpStatus.PAYMENT_REQUIRED),

    /** HTTP 407：需要代理服务器认证 */
    CLIENT_PROXY_AUTH_REQUIRED("请先通过代理服务器认证", 40701, HttpStatus.PROXY_AUTHENTICATION_REQUIRED),

    /** HTTP 408：请求超时 */
    CLIENT_REQUEST_TIMEOUT("请求超时，请重新发送", 40801, HttpStatus.REQUEST_TIMEOUT),

    /** HTTP 409：资源冲突（如唯一键重复） */
    CLIENT_RESOURCE_CONFLICT("%s已存在：%s", 40901, HttpStatus.CONFLICT),

    /** HTTP 410：资源已永久删除 */
    CLIENT_RESOURCE_GONE("%s已永久删除", 41001, HttpStatus.GONE),

    /** HTTP 411：需要Content-Length头 */
    CLIENT_LENGTH_REQUIRED("请求必须包含Content-Length头", 41101, HttpStatus.LENGTH_REQUIRED),

    /** HTTP 412：预处理条件失败（如If-Modified-Since不满足） */
    CLIENT_PRECONDITION_FAILED("预处理条件失败：%s", 41201, HttpStatus.PRECONDITION_FAILED),

    /** HTTP 413：请求体过大  对应标准状态码：413 Payload Too Large */
    CLIENT_PAYLOAD_TOO_LARGE("请求体过大（最大支持：%s）", 41301, HttpStatus.PAYLOAD_TOO_LARGE),

    /** HTTP 414：URI过长 对应标准状态码：414 URI Too Long */
    CLIENT_URI_TOO_LONG("请求URI过长（最大支持：%s字符）", 41401, HttpStatus.URI_TOO_LONG),

    /** HTTP 415：不支持的媒体类型 */
    CLIENT_MEDIA_TYPE_UNSUPPORTED("不支持的媒体类型：%s", 41501, HttpStatus.UNSUPPORTED_MEDIA_TYPE),

    /** HTTP 416：请求范围不满足（如文件下载范围无效） */
    CLIENT_RANGE_NOT_SATISFIABLE("请求的范围无效（资源总大小：%s）", 41601, HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE),

    /** HTTP 417：期望条件失败（如Expect头不满足 客户端要求 “必须使用 HTTPS”） */
    CLIENT_EXPECTATION_FAILED("服务器无法满足期望：%s", 41701, HttpStatus.EXPECTATION_FAILED),

    /** HTTP 429：请求频率过高 */
    CLIENT_TOO_MANY_REQUESTS("请求频率过高，请%d秒后再试", 42901, HttpStatus.TOO_MANY_REQUESTS),

    /* -------------------------- 5xx 服务器错误状态码（500~599） -------------------------- */
    /** HTTP 500：服务器内部错误（通用） */
    SERVER_INTERNAL_ERROR("服务器内部错误，请联系管理员", 50001, HttpStatus.INTERNAL_SERVER_ERROR),

    /** HTTP 500：数据库操作失败 */
    SERVER_DB_ERROR("数据库操作失败：%s", 50002, HttpStatus.INTERNAL_SERVER_ERROR),

    /** HTTP 501：功能未实现 */
    SERVER_NOT_IMPLEMENTED("功能尚未实现：%s", 50101, HttpStatus.NOT_IMPLEMENTED),

    /** HTTP 502：网关错误（后端服务响应无效） */
    SERVER_BAD_GATEWAY("后端服务响应无效", 50201, HttpStatus.BAD_GATEWAY),

    /** HTTP 503：服务不可用（如过载或维护） */
    SERVER_SERVICE_UNAVAILABLE("服务维护中，预计%s后恢复", 50301, HttpStatus.SERVICE_UNAVAILABLE),

    /** HTTP 504：网关超时（后端服务响应超时） */
    SERVER_GATEWAY_TIMEOUT("后端服务响应超时", 50401, HttpStatus.GATEWAY_TIMEOUT),

    /** HTTP 505：不支持的HTTP版本 */
    SERVER_HTTP_VERSION_UNSUPPORTED("不支持HTTP/%s版本", 50501, HttpStatus.HTTP_VERSION_NOT_SUPPORTED);

    /** 错误消息模板（支持占位符） */
    private String msgTemplate;
    /** 自定义业务码（HTTP状态码*100 + 细分编号） */
    private final int bizCode;
    /** 对应的HTTP状态码（使用Spring的HttpStatus枚举） */
    private final HttpStatus httpStatus;

    /**
     * 格式化消息模板
     *
     * @param args 替换占位符的参数
     * @return 格式化后的枚举实例
     */
    public ErrorConstants format(Object... args) {
        this.msgTemplate = String.format(msgTemplate, args);
        return this;
    }

    /**
     * 获取HTTP状态码的数值（如200、404）
     */
    public int getHttpStatusCode() {
        return httpStatus.value();
    }
}
